package com.jungle.client.control;

import com.jungle.client.event.SaveEvent;
import javafx.event.Event;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.ToggleButton;
import javafx.util.Callback;
import lombok.extern.slf4j.Slf4j;

import java.util.function.BiConsumer;
@Slf4j
public class ToggleButtonTableCell<S, T> extends TableCell<S, T> {

    private final ToggleButton toggleButton;
    private final Converter<T, Boolean> converter;


    private static final Converter<String, Boolean> STRING_CONVERTER = new Converter<>() {
        @Override
        public Boolean toTarget(String source) {
            return Boolean.parseBoolean(source);
        }

        @Override
        public String fromTarget(Boolean target) {
            return target == null ? null : target.toString();
        }
    };

    public static <S> Callback<TableColumn<S, Boolean>, TableCell<S, Boolean>> forTableColumn(BiConsumer<S, Boolean> consumer) {
        return param -> new ToggleButtonTableCell<>(null, consumer);
    }

    public static <S> Callback<TableColumn<S, String>, TableCell<S, String>> forString(BiConsumer<S, String> consumer) {
        return param -> new ToggleButtonTableCell<>(STRING_CONVERTER, consumer);
    }

    public ToggleButtonTableCell(Converter<T, Boolean> converter, BiConsumer<S, T> consumer) {
        this.converter = converter;
        toggleButton = new ToggleButton();
        // Style the ToggleButton to look like a switch
        toggleButton.getStyleClass().add("switch-button");

        toggleButton.setOnMouseClicked(event -> {
            T value = fromBoolean(toggleButton.isSelected());

            int rowIndex = this.getIndex();
            TableView<S> tableView = getTableView();
            S item = tableView.getItems().get(rowIndex);
            //updateItem(value,true);
            consumer.accept(item, value);

            //若数据已调置完整，触发保存操作
            Event.fireEvent(tableView, new SaveEvent(rowIndex));
        });
    }

    @Override
    protected void updateItem(T item, boolean empty) {
        super.updateItem(item, empty);
        //log.info("updateItem:{}", item);
        if (empty) {
            setGraphic(null);
        } else {
            toggleButton.setSelected(getBoolean(item));

            setGraphic(toggleButton);
        }
    }

    private boolean getBoolean(T item) {
        return converter == null ? item != null && (Boolean) item : converter.toTarget(item);
    }

    private T fromBoolean(Boolean value) {
        return converter == null ? (T) value : converter.fromTarget(value);
    }
}
